#pragma once

// event_loop事件处理机制
#include <sys/epoll.h>
#include <ext/hash_map>
#include <ext/hash_set>
#include "event_base.h"
#include <vector>

// 一次性能处理事件的最大值
#define MAXEVENTS 10

// map: key:fd--->value:io_event 
typedef __gnu_cxx::hash_map<int, io_event> io_event_map;
//定义指向上面map类型的迭代器
typedef __gnu_cxx::hash_map<int, io_event>::iterator io_event_map_it;
//全部正在监听的fd集合
typedef __gnu_cxx::hash_set<int> listen_fd_set;

// 一般任务的回调函数类型
typedef void (*task_func)(event_loop* loop, void* args);

class event_loop{
public:
    //构造，初始化epoll堆
    event_loop();

    //阻塞循环处理事件
    void event_process();

    //添加一个io事件到loop中
    void add_io_event(int fd, io_callback *proc, int mask, void *args);
    //删除一个io事件从loop中
    void del_io_event(int fd);
    //删除一个io事件的EPOLLIN/EPOLLOUT
    void del_io_event(int fd, int mask);

    // 添加task到_ready_tasks的方法
    void add_task(task_func func, void* args=NULL);
    // 执行_ready_tasks中全部任务的方法
    void execute_ready_tasks();

    // 得到目前在线的fd都有哪些
    void get_fds(listen_fd_set &fds);

private:
    //通过epoll_create创建出来的堆fd
    int _epfd; 

    //当前event_loop 监控的fd和对应事件的关系
    io_event_map _io_evs;

    //当前event_loop 一共哪些fd正在被监听  
    // epoll_wait()在等待的集合，表示目前在线的fd
    listen_fd_set listen_fds;

    //一次性最大处理的事件
    struct epoll_event _fired_evs[MAXEVENTS];

    // 针对异步任务
    typedef std::pair<task_func, void*> task_func_pair;
    // 目前已经就绪的全部任务
    std::vector<task_func_pair> _ready_tasks;
};